<script setup lang="ts">
import { debounce } from '@/utils'
import { useSearchHistoryStore } from '@/stores/search-histore-store'
import Confirm from '@/components/confirm/index.vue'
import {
  getHotKeyword,
  getSearchDefaultKeyword,
  getSearchSuggest,
  getSongsByKeyword
} from '@/api/search'
import { usePlayerStore } from '@/stores/playerStore'
import { getSongUrl } from '@/api/common'
import { processSongPic, processSongUrl } from '@/utils'
import MusicList from '@/components/music-list/index.vue'
import { getSingerSongs, getSongDetail } from '@/api/singer'
import usePaddingBottom from '@/common/use-padding-bottom'
import type { SearchInstance } from 'vant'
const searchRef = ref<SearchInstance>()
const searchHistoryStore = useSearchHistoryStore()
const { paddingBottomStyle } = usePaddingBottom()
const confirmComRef = ref<InstanceType<typeof Confirm> | null>(null)
const keyword = ref<string>('')
const searchSuggestList = ref<{ keyword: string; type: number; processKeyword: string }[]>([])
const showSearchDetail = ref<boolean>(false)
const songList = ref<ISongItem[]>([])
const allSongList = ref<ISongItem[]>([])
const allSongListLoading = ref<boolean>(false)
const songCount = ref<number>(0)
const singerList = ref<ISingerItem[]>([])
const loading = ref<boolean>(false)
const playerStore = usePlayerStore()
const title = ref<string>('')
const pic = ref<string>('')
const singerId = ref<number>()
const showMusicListCom = ref<boolean>(false)
const scrollHeight = ref<number>()
const hotKeywordList = ref<IHotKeywordItem[]>([])
const searchDefaultKeyword = ref<ISearchDefaultKeyword>({
  showKeyword: '',
  realkeyword: '',
  searchType: 0
})
onMounted(async () => {
  const { data } = await getHotKeyword()
  hotKeywordList.value = data
})
watch(
  () => playerStore.showSearch,
  async (newVal: boolean) => {
    const { data } = await getSearchDefaultKeyword()
    searchDefaultKeyword.value = data
    await nextTick()
    if (newVal) {
      searchRef.value?.focus()
    }
  }
)
watch(keyword, debounce(keywordChange, 300))
watch(showSearchDetail, async (newVal: boolean) => {
  if (!newVal) {
    const { data } = await getSearchDefaultKeyword()
    searchDefaultKeyword.value = data
  }
})
async function keywordChange(value: string) {
  if (showSearchDetail.value && value.length > 0) {
    searchHistoryStore.addHistoryRecord(value)
    const {
      result: { allMatch = [] }
    } = await getSearchSuggest(value)
    searchSuggestList.value = allMatch
    const reg = new RegExp(value, 'g')
    for (let i = 0; i < searchSuggestList.value.length; i++) {
      searchSuggestList.value[i].processKeyword = searchSuggestList.value[i].keyword.replace(
        reg,
        '<span style="color:#ffcd32">' + value + '</span>'
      )
    }
    return
  }
  if (value.trim().length === 0) {
    searchSuggestList.value = []
    showSearchDetail.value = false
  } else {
    searchHistoryStore.addHistoryRecord(value)
    const {
      result: { allMatch = [] }
    } = await getSearchSuggest(value)
    searchSuggestList.value = allMatch
    const reg = new RegExp(value, 'g')
    for (let i = 0; i < searchSuggestList.value.length; i++) {
      searchSuggestList.value[i].processKeyword = searchSuggestList.value[i].keyword.replace(
        reg,
        '<span style="color:#ffcd32">' + value + '</span>'
      )
    }
  }
}
function searchButtonClick() {
  if (keyword.value.length === 0) {
    historyKeywordClick(searchDefaultKeyword.value.realkeyword)
  } else {
    historyKeywordClick(keyword.value)
  }
}
function clearRecord() {
  confirmComRef.value?.show()
}
// 清空按钮点击事件
function confirmClear() {
  searchHistoryStore.clearHistoryRecord()
}
// 搜索历史选项点击事件
function historyKeywordClick(text: string) {
  showSearchDetail.value = true
  keyword.value = text
  searchSongsAndSingerByKeyword(text)
}
// 热门搜索选项点击事件
function hotKeywordClick(text: string) {
  historyKeywordClick(text)
}
async function searchSongsAndSingerByKeyword(text: string) {
  songCount.value = 0
  singerList.value = songList.value = []
  showSearchDetail.value = true
  loading.value = true
  let height = 0
  try {
    const [songsResult, singerResult] = await Promise.all([
      getSongsByKeyword(text),
      getSongsByKeyword(text, 100)
    ])
    const songs = (songsResult as IGetSongsByKeywordWithType1Res).result.songs
    songCount.value = (songsResult as IGetSongsByKeywordWithType1Res).result.songCount
    singerList.value = (singerResult as IGetSongsByKeywordWithType100Res).result.artists
    const reg = new RegExp(keyword.value, 'g')
    for (let i = 0; i < singerList.value.length; i++) {
      singerList.value[i].highlightName =
        '歌手:' +
        singerList.value[i].name.replace(
          reg,
          '<span style="color:#ffcd32">' + keyword.value + '</span>'
        )
    }
    const ids = songs.map(({ id }) => id)
    const { data: urls } = await getSongUrl(ids)
    // 根据歌曲id获取到对应的url播放地址
    processSongUrl(songs, urls)
    songList.value = songs
    await nextTick()
    height +=
      (document.querySelector('.singer-wrapper')?.clientHeight || 0) +
      (document.querySelector('.search  .van-search')?.clientHeight || 0)
    scrollHeight.value = window.innerHeight - height
  } finally {
    loading.value = false
  }
}
function back() {
  keyword.value = ''
  if (searchSuggestList.value.length > 0) {
    searchSuggestList.value = []
  } else {
    playerStore.showSearch = false
    searchSuggestList.value = []
  }
  showSearchDetail.value = false
  songList.value = []
  songCount.value = 0
  singerList.value = []
  loading.value = false
}
async function selectSinger(singer: ISingerItem) {
  allSongListLoading.value = true
  const { songs } = await getSingerSongs(singer.id)
  const ids = songs.map(({ id }) => id)
  const { data: urls } = await getSongUrl(ids)
  // 根据歌曲id获取到对应的url播放地址
  processSongUrl(songs, urls)
  // 处理歌曲的背景图
  const { songs: data } = await getSongDetail(ids)
  processSongPic(songs, data)
  allSongList.value = songs
  singerId.value = singer.id
  pic.value = singer.img1v1Url
  title.value = singer.name
  showMusicListCom.value = true
  allSongListLoading.value = false
}
function searchFocus() {
  showSearchDetail.value = false
}
function addSongToPlaylist(song: ISongItem) {
  playerStore.addSongToPlaylist(song)
}
</script>

<template>
  <transition name="slide">
    <div v-show="playerStore.showSearch" class="search" @click.stop>
      <span class="icon" @click.stop="back">
        <i class="iconfont2 icon-xitongfanhui" />
      </span>
      <van-search
        ref="searchRef"
        v-model="keyword"
        show-action
        shape="round"
        background="#222"
        :placeholder="
          searchDefaultKeyword.showKeyword.length > 0
            ? searchDefaultKeyword.showKeyword
            : '请输入搜索关键词'
        "
        @focus="searchFocus"
      >
        <template #action>
          <span class="search-btn" @click="searchButtonClick">搜索</span>
        </template>
      </van-search>
      <!--搜索结果区域-->
      <ul v-show="searchSuggestList.length > 0 && !showSearchDetail" class="search-suggest">
        <li
          v-for="suggest of searchSuggestList"
          :key="suggest.keyword"
          class="suggest-item"
          @click.stop="searchSongsAndSingerByKeyword(suggest.keyword)"
        >
          <span class="iconfont2 icon-sousuo"></span>
          <span class="keyword" v-html="suggest.processKeyword" />
        </li>
      </ul>
      <!--搜索历史区域-->
      <section
        v-show="
          searchHistoryStore.historyList.length > 0 &&
          searchSuggestList.length === 0 &&
          !showSearchDetail
        "
        class="search-history"
      >
        <header class="title">
          <span class="text">搜索历史</span>
          <span class="clear">
            <span @click.stop="clearRecord"><i class="iconfont2 icon-lajitong"></i></span>
          </span>
        </header>
        <ul class="list">
          <li
            v-for="item of searchHistoryStore.historyList"
            :key="item"
            class="item"
            @click.stop="historyKeywordClick(item)"
          >
            {{ item }}
          </li>
        </ul>
      </section>
      <!--热搜列表区域-->
      <section
        v-show="hotKeywordList.length > 0 && searchSuggestList.length === 0 && !showSearchDetail"
        class="hot-search"
      >
        <header class="title">
          <span class="text">热搜榜</span>
        </header>
        <ul class="list">
          <li
            v-for="item of hotKeywordList"
            :key="item.searchWord"
            class="item"
            @click.stop="hotKeywordClick(item.searchWord)"
          >
            <span>{{ item.searchWord }}</span>
            <img v-if="item.iconUrl" :src="item.iconUrl" class="icon-url" alt="" />
          </li>
        </ul>
      </section>
      <!--歌手和单曲展示区域-->
      <section v-show="showSearchDetail" class="suggest-search-result">
        <section
          v-if="singerList.length > 0"
          class="singer-wrapper"
          @click.stop="selectSinger(singerList[0])"
        >
          <img class="singer-pic" :src="singerList[0].img1v1Url" alt="" />
          <div class="singer-desc">
            <span class="singer">
              <span class="name" v-html="singerList[0].highlightName"></span>
              <span class="alias">({{ singerList[0].alias.join('') }})</span>
            </span>
            <span class="song-count">歌曲:{{ songCount }}</span>
          </div>
        </section>
        <section class="songs-wrapper" @click.stop>
          <scroll v-loading="loading" :bounce="false" :height="scrollHeight">
            <ul :style="paddingBottomStyle">
              <li
                v-for="song in songList"
                :key="song.id"
                class="song-item"
                @click.stop="addSongToPlaylist(song)"
              >
                <p
                  class="song-name"
                  :class="playerStore.currentSong?.id === song.id ? 'current' : ''"
                >
                  <span class="text">{{ song.name }}</span>
                  <span v-if="song.alia?.length > 0" class="alias">({{ song.alia[0] }})</span>
                  <span v-if="song.tns?.length > 0" class="tns">({{ song.tns[0] }})</span>
                </p>
                <p class="song-desc">
                  <span class="singer-name">{{ song.ar.map((item) => item.name).join('/') }}</span>
                  <span class="separator">-</span>
                  <span class="album-name">{{ song.al.name }}</span>
                </p>
              </li>
            </ul>
          </scroll>
        </section>
      </section>
    </div>
  </transition>
  <confirm
    ref="confirmComRef"
    text="确定清空全部历史记录?"
    confirm-btn-text="清空"
    @confirm="confirmClear"
  />
  <transition name="slide">
    <div v-if="showMusicListCom" class="music-list-wrapper">
      <music-list
        v-model:show-music-list-com="showMusicListCom"
        :song-list="allSongList"
        :title="title"
        :pic="pic"
        :loading="allSongListLoading"
      />
    </div>
  </transition>
</template>

<style scoped lang="scss">
.search {
  padding: 0 10px;
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 120;
  background: $color-background;
  height: 100%;
  .icon {
    position: absolute;
    left: 2px;
    top: 17px;
    font-size: $font-size-large;
    color: #ffffff;
  }
  .search-btn {
    color: #ffffff;
  }
  :deep(.van-search__action) {
    background-color: transparent;
  }
  .search-suggest {
    padding: 0 15px 15px;
    .suggest-item {
      display: flex;
      line-height: 30px;
      .keyword {
        margin-left: 6px;
        flex: 1;
      }
    }
  }

  .search-history,
  .hot-search {
    padding: 0 10px;
    .title {
      display: flex;
      justify-content: space-between;
      align-items: center;
      height: 20px;
      font-size: $font-size-small;
    }
    .list {
      padding: 5px 0;
      .item {
        display: inline-flex;
        align-items: center;
        padding: 5px 10px;
        margin: 0 20px 10px 0;
        border-radius: 10px;
        background: $color-highlight-background;
        font-size: $font-size-small;
        color: $color-text-ll;
        .icon-url {
          margin-left: 5px;
          width: 12px;
          height: 12px;
        }
      }
    }
  }
  .suggest-search-result {
    .singer-wrapper {
      box-sizing: border-box;
      height: 70px;
      padding: 15px;
      display: flex;
      border-radius: 10px;
      background-color: $color-highlight-background;
      .singer-pic {
        width: 40px;
        height: 40px;
        border-radius: 50%;
      }
      .singer-desc {
        margin-left: 10px;
        display: flex;
        flex-direction: column;
        justify-content: space-evenly;
        flex: 1;
        @include no-wrap;
        .singer {
          @include no-wrap;
          .name {
          }
          .alias {
          }
        }
        .song-count {
          font-size: $font-size-small;
        }
      }
    }
    .songs-wrapper {
      overflow: hidden;
      ul {
        padding: 20px;
        background-color: $color-background;
        .song-item {
          display: flex;
          flex-direction: column;
          justify-content: space-evenly;
          height: 50px;
          .song-name {
            color: $color-text-d;
            @include no-wrap;
            .text {
              color: #ffffff;
              font-size: 13px;
            }
            .alias {
              margin-left: 5px;
              color: $color-text-d;
              font-size: 13px;
            }
            &.current {
              color: $color-theme;
              .text {
                color: $color-theme;
              }
              .alias,
              .tns {
                color: $color-theme;
              }
            }
          }
          .song-desc {
            color: $color-text-d;
            @include no-wrap;
            .singer-name {
              font-size: $font-size-small;
            }
            .separator {
              margin: 0 5px;
            }
            .album-name {
              font-size: $font-size-small;
            }
          }
        }
      }
    }
  }
}
.music-list-wrapper {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 120;
  background-color: $color-background;
}
</style>
